package com.ra.landlord;

import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.annotation.Resource;

import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.ServletActionContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.espirit.eap.ValidationUtil;
import com.espirit.eap.sa.LoginUser;
import com.espirit.eap.sa.LoginUserService;
import com.googlecode.cswish.annotation.Rest;
import com.googlecode.cswish.exception.ApplicationException;
import com.googlecode.cswish.model.PageInfo;
import com.googlecode.cswish.oosearch.Condition;
import com.googlecode.cswish.security.SafeManager;
import com.googlecode.cswish.struts.ContextHolder;
import com.googlecode.cswish.struts.spring.GenericJPAService;
import com.googlecode.cswish.struts.spring.GenericService;
import com.ra.coupon.UserCoupon;
import com.ra.coupon.UserCouponService;
import com.ra.external.WeixinUserService;
import com.ra.util.DateTimeUtil;
import com.ra.util.SmsService;
import com.ra.weixin.WeixinUser;

/**
 * 租客APP注册
 * 
 * 废弃TenantUser, 使用WeixinUser替代			2005/7/17
 * 
 * @author Jerry.feng 2014-09-04
 * 
 */
@Service
public class TenantUserService {

	private final static Log logger = LogFactory.getLog(TenantUserService.class);
	
	@Resource
	private LoginUserService loginUserService;
	
	@Resource
	private GenericJPAService genericJPAService;
	
	@Resource
	private GenericService genericService;
	
	@Resource
	private ValidationUtil validationUtil;
	
	@Resource
	private SmsService smsService;
	
	@Resource
	private SafeManager safeManager;
	
	@Resource
	private WeixinUserService weixinUserService;
	
	@Resource
	private UserCouponService userCouponService;
	
	@Rest(simpleServiceName = "anonymity", type = "free")
	public boolean login(String name, String password) {
		loginUserService.login(name, password, false, ContextHolder.get().getSiteName());
		return true;
	}
	
	@Rest(simpleServiceName = "anonymity", type = "free")
	public boolean checkPhone(String phone) {
		if (StringUtils.isEmpty(phone)) {
			throw new ApplicationException("请输入手机号");
		}
		if (!isMobilePhone(phone)) {
			throw new ApplicationException("手机号码格式不正确");
		}
		
		LoginUser example = new LoginUser();
		example.setName(phone);		// use phone as the login name
		LoginUser dbLoginUser = genericService.searchByModel(example, Condition.SEARCH_ONE).getData(0);
		boolean pass = (dbLoginUser == null);
		if (!pass) {
			throw new ApplicationException("该手机号已经被注册,您可以直接登录使用,如忘记密码,可申请重置");
		}
		return pass;
	}
	
	private boolean isMobilePhone(String mobile) {
		boolean flag = false;
		try {
			Pattern p = Pattern.compile("^((13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$");
			Matcher m = p.matcher(mobile);
			flag = m.matches();
		} catch (Exception e) {
			flag = false;
		}
		return flag;
	}
	
	/**
	 * 注: 只是添加LoginUser信息, 并非添加TenantUser
	 * 
	 * @param model
	 * @param verifyCode
	 * @return
	 */
	@Rest(simpleServiceName = "anonymity", type = "free")
	@Transactional
	public Map<String, Object> register(WeixinUser model, String verifyCode, Integer sourceFrom, String sourceChannel) {
		Map<String, Object> result = new HashMap<String, Object>();
		if (StringUtils.isEmpty(model.getPhone())) {
			throw new ApplicationException("请输入手机号");
		}
		if (validationUtil.hasDuplicateProperty(model)) {
			throw new ApplicationException("该手机号已经被注册,您可以直接登录使用,如忘记密码,可申请重置");
		}
		String existedVerifyCode = smsService.getVerifyCode(model.getPhone());
		if (StringUtils.isEmpty(existedVerifyCode) || !existedVerifyCode.equals(verifyCode)) {
			throw new ApplicationException("验证码无效", verifyCode);
		}
		
		
		LoginUser example = new LoginUser();
		example.setName(model.getPhone());		// use phone as the login name
		LoginUser dbLoginUser = genericService.searchAll(example).getData(0);
		if (dbLoginUser == null) {
			example.setPassword(model.getPassword());
			dbLoginUser = loginUserService.add(example, null, null);
		} else {
			String newPassword = loginUserService.getEncryptPassword(model.getPassword());
			String oldPassword = dbLoginUser.getPassword();
			if (!StringUtils.equals(newPassword, oldPassword)) {
				throw new ApplicationException("该帐户已经存在，请正确填写原先设定的密码");
			}
		}
		
		WeixinUser weixinUser = new WeixinUser();
		weixinUser.setLoginUser(dbLoginUser);
		weixinUser.setPhone(model.getPhone());
		weixinUser.setSourceFrom(sourceFrom);
		weixinUser.setSourceChannel(sourceChannel);
		weixinUserService.addWeixinUser(weixinUser, dbLoginUser);
		
		//boolean fetchedCoupon = createUserCoupon(model.getPhone());
		//result.put("fetchedCoupon", fetchedCoupon);
		
		Integer loginUserId = dbLoginUser.getId();
		safeManager.login(ServletActionContext.getRequest(), String.valueOf(loginUserId), ContextHolder.get().getSiteName());
		return result;
	}
	
	/**
	 * 创建租房券
	 * @param phone
	 * @return
	 */
	private boolean createUserCoupon(String phone) {
		boolean result = false;
		String activityEndTime = userCouponService.getActivityEndTime("milliActivity");
		
		if (StringUtils.isNotBlank(activityEndTime)) {
			try {
				Date endTime = DateTimeUtil.StrToDate(activityEndTime,DateTimeUtil.DATETIME_FORMAT);
				Date currentTime = Calendar.getInstance().getTime();
				if (currentTime.before(endTime)) {
					UserCoupon modelUserCoupon = new UserCoupon();
					modelUserCoupon.setPhone(phone);
					UserCoupon userCoupon = userCouponService.addUserCoupon(modelUserCoupon);
					if (userCoupon != null) {
						result = true;
					}
				}
			} catch (Exception e) {
				logger.error("注册时创建租房券失败。",e);
			}
		}
		return result;
	}
	
	/**
	 * 只是修改LoginUser和LandlordUser的密码
	 * 
	 * @param model
	 * @param verifyCode
	 * @return
	 */
	@Rest(simpleServiceName = "anonymity", type = "free")
	public boolean resetPassword(WeixinUser model, String verifyCode) {
		String existedVerifyCode = smsService.getVerifyCode(model.getPhone());
		boolean pass = StringUtils.isNotEmpty(existedVerifyCode) && existedVerifyCode.equals(verifyCode);
		if (!pass) {
			throw new ApplicationException("验证码无效", verifyCode);
		}
		if (StringUtils.isEmpty(model.getPhone())) {
			throw new ApplicationException("电话号码未填写", model.getPhone());
		}
		
		// 重启loginUser密码
		LoginUser loginUser = new LoginUser();
		loginUser.setName(model.getPhone());
		LoginUser dbLoginUser = genericService.searchAll(loginUser).getData(0);
		if (dbLoginUser == null) {
			throw new ApplicationException("电话号码在系统中不存在", model.getPhone());
		}
		String encryptPassword = loginUserService.getEncryptPassword(model.getPassword());
		dbLoginUser.setPassword(encryptPassword);
		genericService.merge(dbLoginUser);
		
		// 是否为房东
		LandlordUser landlordUser = new LandlordUser();
		landlordUser.setLoginUser(dbLoginUser);
		LandlordUser dbLandlordUser = genericService.searchAll(landlordUser).getData(0);
		if (dbLandlordUser != null) {
			// 同步修改房东密码 (Only for VC)
			dbLandlordUser.setPassword(getVCEncryptPassword(model.getPassword()));
			genericService.merge(dbLandlordUser);
		}
		return true;
	}
	
	private String getVCEncryptPassword(String password) {
		try {
			byte[] encryptPassword = MessageDigest.getInstance("MD5").digest(password.getBytes());
			return Hex.encodeHexString(encryptPassword);
		} catch (Exception e) {
			logger.error("Failed to encrypt password", e);
			return password;
		}
	}
	
    @Rest(type="update")
	public TenantUser updateTenantUser(TenantUser tenantUser) {
    	TenantUser curUser = genericJPAService.load(tenantUser);
    	curUser.setPhone(tenantUser.getPhone());
		return genericJPAService.merge(curUser);
	}
    
    /**
     * 通过【手机号+身份证后4位】查询用户信息
     * 
     * @param model
     * @param verifyCode
     * @return
     */
    @Rest(simpleServiceName = "anonymity", type = "free")
    @Deprecated
    public TenantUser verifyTenantUserInfo(String phone,String simpleIdCard) {
    	if (StringUtils.isEmpty(phone)) {
			throw new ApplicationException("电话号码未填写");
		}
    	
    	TenantUser model = new TenantUser();
    	model.setPhone(phone);
    	PageInfo<TenantUser> tenantUsers = genericService.searchAll(model);
    	List<TenantUser> matchedList = new ArrayList<>();
    	for (TenantUser tenantUser : tenantUsers.getData()) {
    		String idCard = tenantUser.getIdCard();
    		
			if (StringUtils.isNotBlank(idCard) && idCard.length() >=4) {
				String idPart = idCard.substring(idCard.length()-4, idCard.length());
				if (idPart.equalsIgnoreCase(simpleIdCard)) {
					matchedList.add(tenantUser);
				}
			}
		}
    	
    	// FIXME：租客被多个房东录入，取时间最新的. (有更好的方案?)
    	TenantUser lastedUser = null;
    	Date register = null;
    	for (TenantUser tenantUser : matchedList) {
    		if (tenantUser.getRegister() != null && (register == null || tenantUser.getRegister().compareTo(register) > 0)) {
    			register = tenantUser.getRegister();
    			lastedUser = tenantUser;
    		}
    	}
    	return lastedUser;
    }
    
    @Rest(type="search")
	public List<TenantUser> searchTenantUser(TenantUser model) {
		return genericService.searchAll(model).getData();
	}
    
    @Rest(type="search")
	public TenantUser searchTenantUserByIdcard(String idCard) {
    	if (StringUtils.isEmpty(idCard)) {
			throw new ApplicationException("身份证号码未填写");
		}
    	
    	TenantUser tenantUser = null;
    	TenantUser model = new TenantUser();
    	model.setIdCard(idCard);
    	
    	List<TenantUser> tenantUsers = genericService.searchAll(model).getData();
    	
    	if (tenantUsers != null && tenantUsers.size() > 0) {
    		tenantUser = tenantUsers.get(0);
		}
		return tenantUser;
	}
    
    /**
     * 根据当前登录用户查询对应租客用户集合
     * @return 租客用户集合
     */
    public List<TenantUser> searchTenantUsersByLoginUser() {
    	LoginUser loginUser = loginUserService.getLoginUser();
    	TenantUser queryModel = new TenantUser();
    	queryModel.setLoginUser(loginUser);
    	List<TenantUser> tenantUsers = genericService.searchAll(queryModel).getData();
    	return tenantUsers;
    }
    
    /**
     * 修改租客的信息
     * @param tenantUser
     * @return
     */
    @Rest(type="update")
   	public TenantUser modifyTenantUser(TenantUser tenantUser) {
       	TenantUser curUser = genericJPAService.load(tenantUser);
       	curUser.setPhotoFileName(tenantUser.getPhotoFileName());
       	curUser.setAliase(tenantUser.getAliase());
       	curUser.setPhone(tenantUser.getPhone());
       	curUser.setIdCard(tenantUser.getIdCard());
       	curUser.setGender(tenantUser.getGender());
       	curUser.setAddress(tenantUser.getAddress());
   		return genericJPAService.merge(curUser);
   	}
}
